import java.awt.*;
import java.awt.geom.Rectangle2D;

public class GridMap {
	
	boolean grid[][];
	int grid_width, grid_height, grid_resolution;
	int grid_x, grid_y, grid_max_x, grid_max_y;

	public GridMap(int x, int y, int width, int height, int resolution) throws Exception {
		if(width % resolution > 0 || height % resolution > 0) {
			Exception e = new Exception("GridMap: Resolution doesn't match width or height");
			throw e; // If width or height is not divided evenly through resolution, throw exception
		}
		grid_x = x;
		grid_y = y;
		grid_width = width;
		grid_height = height;
		grid_resolution = resolution;
		grid_max_x = width / resolution;
		grid_max_y = height / resolution;
		grid = new boolean[grid_max_x][grid_max_y];
		clearGrid();
	}
	
	public void clearGrid() {
		for(int y = 0; y < grid_max_y; y++) {
			for(int x = 0; x < grid_max_x; x++) {
				grid[x][y] = false;
			}
		}
	}
	
	public Point translatePoint(int x, int y) { // x, y = mousecoords
		// Translate grid to 0, 0; so grid and coords are in the same system
		x = x - grid_x; 
		y = y - grid_y;
		
		// Map coords to grid position
		Point mapped = new Point();
		mapped.x = x / grid_resolution;
		mapped.y = y / grid_resolution;
		
		return mapped;
	}
	
	public Point detranslatePoint(int x, int y) { // x, y = gridcoords
		x *= grid_resolution;
		y *= grid_resolution;
		
		x += grid_x;
		y += grid_y;
		
		x += (grid_resolution / 2);
		y += (grid_resolution / 2);
		
		return new Point(x, y);
	}
	
	public void mapPoint(int x, int y) { // x, y = mousecoords
		Point mapped = translatePoint(x, y);
		try { grid[mapped.x][mapped.y] = true; } catch(Exception e) {}
	}
	
	public void mapRect(int x, int y, int width, int height) { // x, y = mousecoords
		Point start = translatePoint(x, y);		// After this grid system starts at 0, 0
		if(start.x < 0) start.x = 0;
		if(start.y < 0) start.y = 0;
		
		Point end = translatePoint(x + width, y + height);
		if(end.x >= grid_max_x) end.x = grid_max_x - 1;
		if(end.y >= grid_max_y) end.y = grid_max_y - 1; 
		
		for(int ex = start.x; ex < end.x+1; ex++) {
			for(int ey = start.y; ey < end.y+1; ey++) {
				grid[ex][ey] = true;
			}
		}
	}
	
	public void mapFill(Graphics2D g2d, int x, int y) { // x, y = mousecoords
		Point mapped = translatePoint(x, y);
		if(mapped.x >= 0 && mapped.y >= 0)
			fillTile(g2d, mapped.x, mapped.y);
	}
	
	public void fillTile(Graphics2D g2d, int x, int y) { // x, y = gridarraycoords
		g2d.fill(new Rectangle2D.Double(
				(grid_x+x*grid_resolution)+1,
				(grid_y+y*grid_resolution)+1,
				grid_resolution-1,
				grid_resolution-1));
	}
	
	public void drawGrid(Graphics2D g2d) {
		for(int y = 0; y < grid_max_y; y++) {
			for(int x = 0; x < grid_max_x; x++) {
				g2d.setColor(Color.gray);
				g2d.drawRect(grid_x+x*grid_resolution, grid_y+y*grid_resolution, grid_resolution, grid_resolution);
			}
		}
	}
	
	public void drawUnpassable(Graphics2D g2d) {
		for(int y = 0; y < grid_max_y; y++) {
			for(int x = 0; x < grid_max_x; x++) {
				g2d.setColor(Color.red);
				if(grid[x][y])
					fillTile(g2d, x, y);
			}
		}
	}

}
